#coding:utf-8
# from __future__ import unicode_literals

from django.db import models

import re
import datetime
from django.utils import timezone

from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from django.core import validators
from django.contrib import auth
from django.core.urlresolvers import reverse_lazy

from django.contrib.auth.models import Permission, GroupManager, AbstractBaseUser, UserManager


from django.utils.http import urlquote

def private_key_file_url(instance, filename):
    """
    生成私钥文件目录，包含用户名，文件原来的名字，还有日期
    """
    date_format = '%Y-%m-%d'
    now = datetime.datetime.now()
    #now.strftime('%Y-%m-%d')
    url = "private/%s/%s/%s" % (instance.username, now.strftime(date_format), filename)
    return url

def public_key_file_url(instance, filename):
    """
    """
    date_format = '%Y-%m-%d'
    now = datetime.datetime.now()
    url = "public/%s/%s/%s" % (instance.username, now.strftime(date_format), filename)
    return url

# A few helper functions for common logic between User and AnonymousUser.
def _user_get_all_permissions(user, obj):
    permissions = set()
    for backend in auth.get_backends():
        if hasattr(backend, "get_all_permissions"):
            if obj is not None:
                permissions.update(backend.get_all_permissions(user, obj))
            else:
                permissions.update(backend.get_all_permissions(user))
    return permissions


def _user_has_perm(user, perm, obj):
    for backend in auth.get_backends():
        if hasattr(backend, "has_perm"):
            if obj is not None:
                if backend.has_perm(user, perm, obj):
                    return True
            else:
                if backend.has_perm(user, perm):
                    return True
    return False


def _user_has_module_perms(user, app_label):
    for backend in auth.get_backends():
        if hasattr(backend, "has_module_perms"):
            if backend.has_module_perms(user, app_label):
                return True
    return False


# Create your models here.
class GroupManager(models.Manager):
    """
    The manager for the auth's Group model.
    """
    def get_by_natural_key(self, name):
        return self.get(name=name)

@python_2_unicode_compatible
class MyGroup(models.Model):
    """自定义组"""

    name = models.CharField('用户组/代理', max_length=80, unique=True)
    name_for_short = models.CharField('平台名英文缩写', max_length=100, help_text='最多100个英文字母长', unique=True)
    permissions = models.ManyToManyField(Permission,
        verbose_name='permissions', blank=True)
    preserved = models.CharField('保留字段', max_length=100)

    objects = GroupManager()

    class Meta:
        verbose_name = '用户组/代理'
        verbose_name_plural = verbose_name
        permissions = (
        ('list_mygroup', '查看'+verbose_name),
        )

    def __str__(self):
        return self.name

    def natural_key(self):
        return (self.name,)

class PermissionsMixin(models.Model):
    """
    A mixin class that adds the fields and methods necessary to support
    Django's Group and Permission model using the ModelBackend.
    """
    is_superuser = models.BooleanField('超级用户 status', default=False,
        help_text='如果设置选择了这个参数，账号将会拥有所有权限，而且不需要指定!')

    groups = models.ManyToManyField(MyGroup, verbose_name='groups',
                                    blank=True, help_text='账号所属的组，可以多个。账号拥有对应组的所有权限')
    user_permissions = models.ManyToManyField(Permission,
        verbose_name='user permissions', blank=True,
        help_text='指定这个用户的权限')

    class Meta:
        abstract = True

    def get_group_permissions(self, obj=None):
        """
        Returns a list of permission strings that this user has through his/her
        groups. This method queries all available auth backends. If an object
        is passed in, only permissions matching this object are returned.
        """
        permissions = set()
        for backend in auth.get_backends():
            if hasattr(backend, "get_group_permissions"):
                if obj is not None:
                    permissions.update(backend.get_group_permissions(self,
                                                                     obj))
                else:
                    permissions.update(backend.get_group_permissions(self))
        return permissions

    def get_all_permissions(self, obj=None):
        return _user_get_all_permissions(self, obj)

    def has_perm(self, perm, obj=None):
        """
        Returns True if the user has the specified permission. This method
        queries all available auth backends, but returns immediately if any
        backend returns True. Thus, a user who has permission from a single
        auth backend is assumed to have permission in general. If an object is
        provided, permissions for this specific object are checked.
        """

        # Active superusers have all permissions.
        if self.is_active and self.is_superuser:
            return True

        # Otherwise we need to check the backends.
        return _user_has_perm(self, perm, obj)
    def has_perms(self, perm_list, obj=None):
        """
        Returns True if the user has each of the specified permissions. If
        object is passed, it checks if the user has all required perms for this
        object.
        """
        for perm in perm_list:
            if not self.has_perm(perm, obj):
                return False
        return True

    def has_module_perms(self, app_label):
        """
        Returns True if the user has any permissions in the given app label.
        Uses pretty much the same logic as has_perm, above.
        """
        # Active superusers have all permissions.
        if self.is_active and self.is_superuser:
            return True

        return _user_has_module_perms(self, app_label)



class AbstractUser(AbstractBaseUser, PermissionsMixin):
    """模仿的自定义抽象User"""
    username = models.CharField('账号名', max_length=30, unique=True,
        help_text=_('Required. 30 characters or fewer. Letters, numbers and '
                    '@/./+/-/_ characters'),
        validators=[
            validators.RegexValidator(re.compile('^[\w.@+-]+$'), _('Enter a valid username.'), 'invalid')
        ])
    email = models.EmailField('邮箱', blank=True)
    is_staff = models.BooleanField(_('staff status'), default=False,
        help_text='指定是否可以登陆后台')
    is_active = models.BooleanField(_('active'), default=True,
        help_text='指定账号是否是可用的，反选这个选项而可以删除账号!')
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    objects = UserManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        abstract = True

    def get_absolute_url(self):
        return "/users/%s/" % urlquote(self.username)

    def get_full_name(self):
        """
        Returns the first_name plus the last_name, with a space in between.
        """
        full_name = '%s %s' % (self.first_name, self.last_name)
        return self.name if self.name else self.username

    def get_short_name(self):
        "Returns the short name for the user."
        return self.name if self.name else self.username



class MyUser( AbstractUser):
    """
    自定义用户
    """
    MANAGER='manager'
    DEVELOP = 'develop'
    BUSINESS = 'business'
    MAINTAIN = 'maintai'
    USER_TYPE_CHOICES=(
        (MANAGER,'管理员'),
        (DEVELOP,'开发'),
        (BUSINESS,'运营'),
        (MAINTAIN,'运维'),
    )
    name = models.CharField('名字',max_length=100)
    user_type = models.CharField('账号类型',max_length=100, choices = USER_TYPE_CHOICES)
    private_key_file = models.FileField(upload_to=private_key_file_url, verbose_name='私钥文件', blank=True, null=True)
    private_key_passwd = models.CharField('私钥密码',max_length=100, blank=True, null=True)
    public_key_file = models.FileField(upload_to=public_key_file_url, verbose_name='公钥文件', blank=True, null=True)

    def __str__(self):
        return self.name if self.name else self.username

    class Meta:
        verbose_name = '账号'
        verbose_name_plural = '账号'
        permissions = (
        ('list_myuser', '查看' + verbose_name),
        )

class PlatForm( models.Model):
    name = models.CharField('平台名', max_length=100, help_text='最多100个英文字母长', unique=True)
    name_for_short = models.CharField('平台名英文缩写', max_length=100, help_text='最多100个英文字母长', unique=True)
    zoneinfo = models.CharField('时区', max_length=100, help_text='格式: Asia/Shanghai', default='Asia/Shanghai')
    area = models.CharField('地区', max_length=100, default='mainland', help_text="通过这个字段来标识可能合服的平台，同样的标签就可能合服")
    group = models.ForeignKey(MyGroup)

    def get_absolute_url(self):
        return reverse_lazy('myauth:detail_platform', kwargs={'pk':self.pk})

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '平台'
        verbose_name_plural = '平台'
        permissions = (
        ('list_platform', '查看'+verbose_name),
        )

